package com.yangkunhong.utils;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * ClassName: ConfigUtil
 * Description:
 *
 * @author yangkunhong
 * @date 2024/6/25 9:39
 */
public class ConfigUtil {
    public static String getConfigFileName(Class<?> clazz) {
        switch (clazz.getSimpleName()) {
            case "DbConfig":
                return "db.properties";
            case "RedisConfig":
                return "redis.properties";
            case "AliSmsConfig":
                return "aliSms.properties";
            default:
                throw new IllegalArgumentException("Unknown config class name: " + clazz.getSimpleName());
        }

    }
    public static <T> T getConfig( Class<T> clazz) {
        // 获取配置文件流
        String fileName = getConfigFileName(clazz);
        InputStream input = ConfigUtil.class.getClassLoader().getResourceAsStream(fileName);
        Properties prop = new Properties();
        try {
            // 获取文件流对应的字符流 以防中
            Reader reader = new InputStreamReader(input, "UTF-8") ;
            prop.load(reader);
        } catch (IOException e) {
            throw new RuntimeException("Failed to load config file: " + fileName, e);
        }
        Map<String, Object> map = new HashMap<>();
        for (Object key : prop.keySet()) {
            map.put((String) key, prop.get(key));
        }
        return convertMapToObject(map, clazz);
    }
    public static <T> T convertMapToObject(Map<String, Object> map, Class<T> clazz) {
        // 假设有一个无参构造器
        // 使用反射获取单例类的私有构造函数
        Constructor<T> constructor = null;
        try {
            constructor = clazz.getDeclaredConstructor();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        // 设置为可访问，因为构造函数是私有的
        constructor.setAccessible(true);

        // 通过反射创建实例
        T obj = null;
        try {
            obj = constructor.newInstance();
        } catch (InstantiationException | InvocationTargetException | IllegalAccessException e) {
            e.printStackTrace();
        }

        for (Map.Entry<String, Object> entry : map.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();

            // 查找与键对应的字段
            //System.out.println(key);
            Field field = null;
            try {
                field = clazz.getDeclaredField(key);
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            }

            // 确保字段可访问（如果它不是public的）
            field.setAccessible(true);

            // 检查字段类型是否与值兼容，这里只是一个简化的例子，你可能需要更复杂的处理
            if (field.getType().equals(String.class)) {
                if (value instanceof String) {
                    try {
                        field.set(obj, value);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                } else {
                    // 尝试将值转换为字符串
                    try {
                        field.set(obj, value.toString());
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            } else if (field.getType().equals(int.class) || field.getType().equals(Integer.class)) {
                if (value instanceof Number) {
                    try {
                        field.set(obj, ((Number) value).intValue());
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                } else {
                    // 尝试将值转换为整型
                    try {
                        try {
                            field.set(obj, Integer.parseInt(value.toString()));
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    } catch (NumberFormatException e) {
                        throw new IllegalArgumentException("Value cannot be converted to integer for field: " + key, e);
                    }
                }
            } else {
                // 其他类型，你可以根据需要添加更多的类型检查和处理
                if (field.getType().isInstance(value)) {
                    try {
                        field.set(obj, value);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                } else {
                    throw new IllegalArgumentException("Field type does not match value type for field: " + key);
                }
            }
        }

        return obj;
        }
    }
